<?php
/**
 * Parent controller for all public controllers
 *
 */
class Client_Controller extends Zend_Controller_Action
{
    protected $page_type = 'system';

    protected $ceo_title = '';
    protected $ceo_keywords = '';
	protected $ceo_desc = '';

    //protected $table_accounts;

    protected $_table; // current table
	protected $table_categories;
    protected $table_objects;
    protected $table_articles;
    protected $table_privileges;
    protected $table_tags;

    /**
     * Zend_Auth object
     *
     * @var Zend_Auth
     */
    protected $_auth;
    protected $_user;
    protected $_sess;

    protected $_db2;

    protected $_domain_name;

    protected  $_menu_path;

    protected $_path_real;
    protected $_path_files;
    protected $_path_tmp;
    protected $_path_lang_messages;
    protected $_http_files;

    protected $_files; // Llib_Files Object
    protected $_tumb;  // Tumb_images Object

    protected $controller;
    protected $action;

    protected $_menu;
    protected $active_cat = 62; // Active current cat at menu // Root page as default
    protected $active_cat_root = 62; // Root page as default
    protected $root_cat = 62; // Const, root of struct menu

    protected $_lang = 'ua';
    protected $_t;     // Translator

    protected $max_folders_count = 100000; // Const, root of struct menu


    /**
     * Method starts when controller startup
     *
     */
    public function init()
    {
    	//$this->_db2 = Zend_Registry::get('db2');

    	$this->controller = $this->getRequest()->getControllerName();
    	$this->action = $this->getRequest()->getActionName();

    	$this->_sess = new Zend_Session_Namespace($this->controller.'/'.$this->action);
    	//$this->_auth = Zend_Registry::get('auth');
        //$this->_user = $this->_auth->getIdentity();

        $this->_domain_name = Zend_Registry::get('config')->domains->front;

        $this->_path_real =  realpath( dirname(dirname(dirname(__FILE__))));
        //$this->_path_files = $this->_path_real.'/files.'.$this->_domain_name;
        $this->_path_files = $this->_path_real.'/portal/files';
        $this->_path_tmp = $this->_path_files.'/tmp';
        $this->_path_lang_messages = $this->_path_real.'/languages/messages.tmx';

        $this->_http_files = 'http://'.Zend_Registry::get('config')->domains->files;

        $this->_files = new Llib_Files($this->_path_files);
        $this->_lang = $this->_getParam('language', Zend_Registry::get('config')->languages->default);
        if(isset($GLOBALS['lang'])) $this->_lang =  $GLOBALS['lang'];

        $this->table_accounts = new Client_Table_Accounts();
        $this->table_roles = new Client_Table_Role();
        $this->table_rules = new Client_Table_Rule();

        $this->table_categories  = new Client_Table_Categories($this->_lang);
        $this->table_articles = new Client_Table_Articles($this->_lang);
        $this->table_objects = new Client_Table_Objects($this->_lang);
        //$this->table_privileges = new Client_Table_Privileges($this->_lang);
        //$this->table_tags = new Client_Table_Tags();

        $this->InitMenu();
        $this->_initView();
    }

    /**
     * Method initialization of view valiables
     *
     */
    protected  function _initView()
    {
        $this->view->Settings('path', Zend_Registry::get('config')->base_url);
        $this->view->Settings('site_url', Zend_Registry::get('config')->site_url);

        $this->view->Settings('title', Zend_Registry::get('config')->title);

        $this->view->Settings('url', 'http://'.Zend_Registry::get('config')->domains->front);
        $this->view->Settings('files_url', 'http://'.Zend_Registry::get('config')->domains->files);
        $this->view->Settings('images_url', 'http://'.Zend_Registry::get('config')->domains->front.'/images');
        $this->view->Settings('main_url', 'http://'.Zend_Registry::get('config')->domains->front);

        //Settings data added to xml
        $this->view->Settings('user_agent', $_SERVER['HTTP_USER_AGENT']);
        $this->view->Settings('user_agent_arr', explode(' ', $_SERVER['HTTP_USER_AGENT']));
        $this->view->Settings('controller', $this->controller);
        $this->view->Settings('action', $this->action);
        $this->view->Settings('website_name', Zend_Registry::get('config')->website_name);

        $this->_domain_name = Zend_Registry::get('config')->domains->front;

        $curr_url = $this->getRequest()->getServer('REDIRECT_URL');
        $curr_url_arr = explode('/',$curr_url);

		if(isset(Zend_Registry::get('config')->languages->item))
		{
            if(is_array($curr_url_arr) && in_array(@$curr_url_arr[1], Zend_Registry::get('config')->languages->item->toArray()))
            {
            	$this_without_lang = substr($curr_url, 3, strlen($curr_url)-3);
            }
            else $this_without_lang = $curr_url;
            if($this_without_lang == '') $this_without_lang = '/';
            $this->view->Settings('this_without_lang', $this_without_lang);
            $this->view->Settings('langs', Zend_Registry::get('config')->languages->item->toArray());
		}

        $this->view->Settings('this', $curr_url);
        $this->view->Settings('lang', $this->_lang);
    }



    /**
     * Start content tag in result xml
     *
     */
    protected function startContent()
    {
        $this->view->xmlWriter->startElement('content');
        if (!is_null($this->active_cat))$this->view->xmlWriter->writeAttribute('cat', $this->active_cat);
        if (!is_null($this->page_type))$this->view->xmlWriter->writeAttribute('pagetype', $this->page_type);
        if (!is_null($this->ceo_title)) $this->view->assign('ceo_title', $this->ceo_title);
        if (!is_null($this->ceo_keywords)) $this->view->assign('ceo_keywords', $this->ceo_keywords);
        if (!is_null($this->ceo_desc)) $this->view->assign('ceo_desc', $this->ceo_desc);

        $static = $this->table_categories->GetStatic($this->active_cat);

        $this->view->xmlWriter->startElement('static');
        $this->view->assign($static);
        //if($static['is_show_gallery'] == 1)
       		//$this->view->assign('attaches', $this->table_objects->GetDataList(array('id_cat' => $static['id'])));
        $this->view->xmlWriter->endElement();

        $this->_content();
    }

    /**
     * Method, for generation xml content in parent controller
     *
     */
    protected function _content()
    {
    	$currTime = time();

        $use_png_filtered = (strpos($this->getRequest()->getServer('HTTP_USER_AGENT'), 'MSIE') !== false)?(1):(0);
        $this->view->Settings('browser', array('use_png_filtered'=>$use_png_filtered));
        $current_date['current-date']['__attributes'] = Apk_Util::timestampToArray(time());
        $this->view->assign($current_date);

        $this->_menu_path = $this->GetMenuPath();
        $this->view->assign('Path', $this->_menu_path);

        $cats = $this->GetMenu();
        $this->view->xmlWriter->startElement("Cats");
        $this->view->xmlWriter->writeAttribute('root', $this->active_cat_root);
        $this->view->assign($cats);
        $this->view->xmlWriter->endElement();

    	// Authorization information
        //$this->view->xmlWriter->startElement("auth-info");
    	//$this->view->assign('hasIdentity', intval($this->_auth->hasIdentity()));
    	//$this->view->assign('perm', $this->getPerm());

    	/*if($this->_auth->hasIdentity())
    	{
    		$this->view->assign('id', $this->_user->id);
    		$this->view->assign('name', $this->_user->first_name);
    		$this->view->assign('role_id', $this->_user->role_id);
    	}
    	else
    	{
    		$this->view->assign('name', 'guest');
    	}
    	$this->view->xmlWriter->endElement();*/

    	/*$this->view->xmlWriter->startElement("cart");
    		$this->view->assign('items', $this->_cart->getSessionNs()->items);
    		$this->view->assign('count', $this->_cart->getCount());
    		$this->view->assign('total', $this->_cart->getTotal());
    	$this->view->xmlWriter->endElement();


        $this->view->assign('Obed-V-Office', $this->table_categories->GetStatic(810));*/
       // $this->view->assign('Privileges', $this->table_privileges->GetDataList());

         $this->view->assign('Contacts', $this->table_categories->GetStatic(756));
    }

    /**
     *Find element def in not_def by name
     *
     * @param array $not_def
     * @param array $def
     * @return  key or false if not found
     */

    protected static function _findnotDefault($def,$not_def)
    {
        foreach ($not_def as $key => $val){
            if (  $val['name'] == $def['name']) return $key;
        }
        return false;
    }

    /**
     * Close content tag in result xml.
     *
     */
    protected function endContent()
    {
        $this->view->xmlWriter->endElement();
    }


    public function getFileAdapter()
    {
    	$adapter = new Zend_File_Transfer_Adapter_Http();
    	$adapter->setOptions(array('ignoreNoFile'=>1));
    	$adapter->addValidator('Size', false, array('min' => 0, 'max' => 6000000));
    	$adapter->addValidator('Extension', false, array('jpg', 'png', 'gif', 'case' => false));
    	$adapter->setDestination($this->_path_tmp);

    	$this->createTumbAdapter();
    	return $adapter;
    }

    public function createTumbAdapter()
    {
    	require_once 'Tumb/ThumbLib.inc.php';
    	$this->_tumb = new PhpThumbFactory;
    }

	public function LoadObjects($id, &$form, $field = 'id_gallery', $controller = 'objects')
	{
	    $k = 100000;
		if(is_null($controller)) $controller = $this->controller;

		$this->_files->CreateFolder('/'.$controller);
        $adapter = $this->getFileAdapter();

        if ($adapter->receive()) {
    		$files = $adapter->getFileInfo();

    		foreach($files as $file)
    		{
    			$id_object = $this->table_objects->insert(array($field => $id), 0);

		    	$this->_files->CreateFolder(intval($id_object/$k), '/'.$controller);
		    	$this->_files->CreateFolder($id_object, '/'.$controller.'/'.intval($id/$k));
		    	$path = '/'.$controller.'/'.intval($id_object/$k).'/'.$id_object.'/';

    			$image = $this->LoadImage($file, $path, $id_object, $controller, true);

    			$this->table_objects->update($image, $id_object, 0);
    		}
    	}
    	else
    	{
		    $messages = $adapter->getMessages();
		    $errors = $adapter->getErrors();
		    if(is_object($form))  $form->SetError(implode("\n", $messages).implode("\n", $errors));
		    else echo implode("\n", $messages).implode("\n", $errors);
    	}

    	return 1;
	}

	public function LoadObject($id, &$form, $field = 'id_gallery', $controller = 'objects', &$id_object = 0, $user_id = 0, &$image = array())
	{
	    $k = $this->max_folders_count;
		if(is_null($controller)) $controller = $this->controller;

		$this->_files->CreateFolder('/'.$controller);
        $adapter = $this->getFileAdapter();

        if ($adapter->receive()) {
			$files = $adapter->getFileInfo();
			$file = $files['Filedata'];

			$id_object = $this->table_objects->insert(array($field => $id), $user_id);

	    	$this->_files->CreateFolder(intval($id_object/$k), '/'.$controller);
	    	$this->_files->CreateFolder($id_object, '/'.$controller.'/'.intval($id/$k));
	    	$path = '/'.$controller.'/'.intval($id_object/$k).'/'.$id_object.'/';

			$image = $this->LoadImage($file, $path, $id_object, $controller, true, true);

			$this->table_objects->update($image, $id_object, $user_id);
    	}
    	else
    	{
		    $messages = $adapter->getMessages();
		    $errors = $adapter->getErrors();
		    if(is_object($form))  $form->SetError(implode("\n", $messages).implode("\n", $errors));
		    else echo implode("\n", $messages).implode("\n", $errors);
    	}

    	return 1;
	}

	public function LoadAvatar($id, &$form, &$d, $controller = null)
	{
	    $k = $this->max_folders_count;
		if(is_null($controller)) $controller = $this->controller;

		$this->_files->CreateFolder('/'.$controller);
        $adapter = $this->getFileAdapter();

    	$this->_files->CreateFolder(intval($id/$k), '/'.$controller);
    	$this->_files->CreateFolder($id, '/'.$controller.'/'.intval($id/$k));
    	if($_FILES['avatar']['name'] != '') $this->_files->EmptyFolder('/'.$controller.'/'.intval($id/$k).'/'.$id);

    	$path = '/'.$controller.'/'.intval($id/$k).'/'.$id.'/';
    	$adapter->setDestination($this->_path_files.$path);

        if ($adapter->receive()) {
    		$files = $adapter->getFileInfo();

    		$image = $this->LoadImage($files['avatar'], $path, $id, $controller);
    		$d = array_merge($d, $image);
    	}
    	else
    	{
		    $messages = $adapter->getMessages();
		    $errors = $adapter->getErrors();
		    $form->SetError(implode("\n", $messages).implode("\n", $errors));
    	}

    	return 0;
	}

	public function LoadAvatarFromFile($file, $id, &$d, $controller = null)
	{
	    $k = $this->max_folders_count;

    	if(trim($file['path']) == '') return array();
    	if(!($id > 0)) return array();

		if(is_null($controller)) $controller = $this->controller;

		$this->_files->CreateFolder('/'.$controller);
        $adapter = $this->getFileAdapter();

    	$this->_files->CreateFolder(intval($id/$k), '/'.$controller);
    	$this->_files->CreateFolder($id, '/'.$controller.'/'.intval($id/$k));

    	$this->_files->EmptyFolder('/'.$controller.'/'.intval($id/$k).'/'.$id);

    	$path = '/'.$controller.'/'.intval($id/$k).'/'.$id.'/';

    	copy($this->_path_files.$file['path'].$file['name'], $this->_path_files.$path.$file['name']);

    	$image = $this->LoadImage($file, $path, $id, $controller);
    	$d = array_merge($d, $image);

    	return 0;
	}

    /**
     * Load image with diff sizes
     *
     * @param array $file - loaded image file
     * @param string $path - /controller/id/
     * @param array $data - old loaded data
     *
     * @return data for updates
     */

    public function LoadImage($file, $path, $id, $controller = null, $is_tmp = false)
    {
    	if(!($file['error'] == 0 && (
    		   $file['type'] == 'image/jpeg'
    		|| $file['type'] == 'application/octet-stream')
    	)) return array();

    	if(trim($path) == '') return array();
    	if(!($id > 0)) return array();

    	require_once 'Tumb/ThumbLib.inc.php';

    	if(is_null($controller)) $sizes = Zend_Registry::get('config')->images->modules->{$this->controller}->toArray();
    	else $sizes = Zend_Registry::get('config')->images->modules->{$controller}->toArray();
    	$d = array();

    	$file_name = time().'.jpg';

    	foreach($sizes as $type => $size)
    	{
				if($is_tmp) $thumb = $this->_tumb->create($this->_path_tmp.'/'.$file['name']);
    			else $thumb = $this->_tumb->create($this->_path_files.$path.$file['name']);

    			switch($size['type'])
				{
					case 'Strict':
						$thumb->adaptiveResize($size['width'], $size['height']);
						break;
					default:
						$thumb->resize($size['width'], $size['height']);
						break;
				}

	    		$thumb->save($this->_path_files.$path.($id.$type.$file_name));

				$d['original_file_name'] = $file['name'];
	    		$d['file_name'] = $file_name;
				$d['path'] = $path;
    	}

		if($is_tmp) $thumb = $this->_tumb->create($this->_path_tmp.'/'.$file['name']);
		else $thumb = $this->_tumb->create($this->_path_files.$path.$file['name']);
		$thumb->save($this->_path_files.$path.($file_name));


    	if($is_tmp)	$this->_files->RemoveFile('/tmp/'.$file['name']);

		return $d;
    }


    public function SessionVars($data, $vars = array(), $rest = 0)
    {
    	$ret = array();

    	if($rest){
    		foreach($vars as $var)
    		{
    			switch($var)
    			{
    				case 'search_text':
    					$this->_sess->{$var} = '';
    					break;
    				default:
    				   $this->_sess->{$var} = -1;
    			}
    			$ret[$var] = $this->_sess->{$var};
    		}
    		return $ret;
    	}

    	foreach($data as $k=>$v)
    	{
    		if(isset($v) && $v != '')
    			$this->_sess->{$k} = $v;
    	}

    	foreach($vars as $var)
    		$ret[$var] = $this->_sess->{$var};

    	return $ret;
    }
    
public function SessionVarsEx($data, $vars = array(), $reset = false) {
        $result = array();

        if (!empty($reset)) {
            foreach ($vars as $key => $value) {
                if (is_string($key)) {
                    $this->_sess->{$key} = $value;
                    $result[$key] = $this->_sess->{$key};
                } else {
                    $this->_sess->{$value} = '';
                    $result[$value] = $this->_sess->{$value};
                }
            }
            return $result;
        }

        foreach ($data as $key => $value) {
            if (isset($value)) {
                $this->_sess->{$key} = $value;
            }
        }

        foreach ($vars as $key => $value) {
            if (is_string($key)) {
                if (!isset($this->_sess->{$key})) {
                    $this->_sess->{$key} = $value;
                }
                $result[$key] = $this->_sess->{$key};
            } else {
                if (!isset($this->_sess->{$value})) {
                    $this->_sess->{$value} = '';
                }
                $result[$value] = $this->_sess->{$value};
            }
        }

        return $result;
    }

public function setActiveCat($id)
    {
    	$this->active_cat = $id;
    	$cat = $this->table_categories->GetStatic($id);
		$this->active_cat_arr = $cat;

		$this->setCEO($cat);

    }

    public function setCEO(&$data)
    {

    	if(isset($data['ceo_title']) && trim($data['ceo_title']) != '') $this->ceo_title = $data['ceo_title'];
    	elseif(isset($data['title'])) $this->ceo_title = $data['title'];
    	elseif(isset($data['name'])) $this->ceo_title = $data['name'];


    	if(isset($data['ceo_desc']) && trim($data['ceo_desc']) != '') $this->ceo_desc = $data['ceo_desc'];
		if(isset($data['ceo_keywords']) && trim($data['ceo_keywords']) != '') $this->ceo_keywords = $data['ceo_keywords'];


    	return $this->ceo_title;
    }

    public function setActiveCatSite($id)
    {
    	$this->active_cat_site = $id;
    }

    public function createTranslater()
    {
    	$this->_t = new Zend_Translate('tmx', $this->_path_lang_messages, $this->_lang);
    }


    //****************************************
    // Menu functions
    //****************************************

    private function InitMenu()
    {
		$params = array(
			'id' => 'id',
			'root_id' => 'rootid',
	    	'l' => 'l',
		    'r' => 'r',
		    'norder' => 'norder',
		    'level' => 'level',
	    	'parent_id'=>'parent',
	    	'menu_name_ru' => 'menu_name_ru',
	    	'menu_name_ua' => 'menu_name_ua',
	    	'menu_name_en' => 'menu_name_en',
	    	'title_ru' => 'title_ru',
	    	'title_ua' => 'title_ua',
	    	'title_en' => 'title_en',
	    	'url' => 'url',
	    	'is_active' => 'is_active',
	    	'text_ru' => 'text_ru',
	    	'text_ua' => 'text_ua',
	    	'text_en' => 'text_en',
	    	'add_date' => 'add_date',
	    	'modify_date' => 'modify_date',
	    	'idt' => 'idt'
	    );

	    $this->_menu =& DB_NestedSet::factory('DBLite', NULL, $params);
	    $this->_menu->factory('DBLite', NULL, $params);
	    $this->_menu->setAttr(array(  'node_table' => 'categories'));
    }

    protected function GetMenuPath()
    {
 		$element = $this->_menu->pickNode($this->active_cat, true);
    	$parents = $this->_menu->getParents($this->active_cat);
 		$path = array();
 		$i=0;


 		if (sizeof($parents)) {
 			foreach($parents as $parent) {
 				if($i>0)
 				{
 					$path[$i]['id'] = $parent->id;
					$path[$i]['name'] = $parent->{'menu_name_'.$this->_lang};
					$path[$i]['url'] = $parent->url;
					$path[$i]['idt'] = $parent->idt;
 				}
					$i++;
 			}
 		}

 		$path[$i]['id'] = $element['id'];
 		$path[$i]['name'] = $element['menu_name_'.$this->_lang];
 		$path[$i]['url'] = $element['url'];
 		$path[$i]['idt'] = $element['idt'];

 		return $path;
    }

    private function GetMenu()
    {
    	$parents = $this->_menu->getParents($this->active_cat);
 		$data = array();
 		if (sizeof($parents)) {
 			foreach($parents as $parent) {
 					$data[] = $parent->id;
 			}
 		}
 		$data[] = $this->active_cat;
 		//$this->active_cat_root = $data[2];

 		//return $this->table_admin_cats->GetMenu($data);


 		return $this->table_categories->GetChildList($this->root_cat, $data, true);
    }

	public function GetResourceName()
	{
		$res = $this->table_categories->GetDataRow($this->active_cat);
		return $res['site'].':'.$res['module'].':'.$res['controller'];
	}

	public function GetRoleName()
	{
		if(isset($this->_user->role_name)) return $this->_user->role_name;
		else return 'guest';
	}

    public function ajaxOut($output = '', $type = 'html')
    {
    	 if($type == 'json') $output = Zend_Json::encode($output);
    	 Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer');
         $response = $this->getResponse();
         $response->setBody($output)->setHeader('content-type', 'application/'.$type, true);

		 $response->sendResponse();
		 die();
	}

    //****************************************
    // Staff function
    //****************************************
    public function MakeSeed() {
	    list($usec, $sec) = explode(' ', microtime());
	    return (float) $sec + ((float) $usec * 100000);
	}
	
private function getTLiteralArray() {
        return array(
            "а" => "a", "б" => "b", "в" => "v", "г" => "g",
            "д" => "d", "е" => "e", "ё" => "e", "ж" => "zh",
            "з" => "z", "и" => "i", "й" => "y", "к" => "k",
            "л" => "l", "м" => "m", "н" => "n", "о" => "o",
            "п" => "p", "р" => "r", "с" => "s", "т" => "t",
            "у" => "u", "ф" => "f", "х" => "h", "ц" => "ts",
            "ч" => "ch", "ш" => "sh", "щ" => "shch", "ъ" => "",
            "ь" => "", "э" => "ie", "ю" => "yu", "я" => "ya",
            "ї" => "yi", "і" => "i", " " => "-", "-" => "-", "ы" => "i",
            "А" => "a", "Б" => "b", "В" => "v", "Г" => "g",
            "Д" => "d", "Е" => "e", "Ё" => "e", "Ж" => "zh",
            "З" => "z", "И" => "i", "Й" => "y", "К" => "k",
            "Л" => "l", "М" => "m", "Н" => "n", "О" => "o",
            "П" => "p", "Р" => "r", "С" => "s", "Т" => "t",
            "У" => "u", "Ф" => "f", "Х" => "h", "Ц" => "ts",
            "Ч" => "ch", "Ш" => "sh", "Щ" => "shch", "Ъ" => "",
            "Ь" => "", "Э" => "ie", "Ю" => "yu", "Я" => "ya",
            "Ї" => "yi", "І" => "i", "Ы" => "I",
            "0" => "0", "1" => "1", "2" => "2", "3" => "3",
            "4" => "4", "5" => "5", "6" => "6", "7" => "7",
            "8" => "8", "9" => "9",
            "a" => "a", "b" => "b", "c" => "c", "d" => "d",
            "e" => "e", "f" => "f", "g" => "g", "h" => "h",
            "i" => "i", "j" => "j", "k" => "k", "l" => "l",
            "m" => "m", "n" => "n", "o" => "o", "p" => "p",
            "q" => "q", "r" => "r", "s" => "s", "t" => "t",
            "u" => "u", "v" => "v", "w" => "w", "x" => "x",
            "y" => "y", "z" => "z",
            "A" => "a", "B" => "b", "C" => "c", "D" => "d",
            "E" => "e", "F" => "f", "G" => "g", "H" => "h",
            "I" => "i", "J" => "j", "K" => "k", "L" => "l",
            "M" => "m", "N" => "n", "O" => "o", "P" => "p",
            "Q" => "q", "R" => "r", "S" => "s", "T" => "t",
            "U" => "u", "V" => "v", "W" => "w", "X" => "x",
            "Y" => "y", "Z" => "z"
        );
    }
    
    public function tstring_filename($inputStr) {
        $t = $this->getTLiteralArray();
        return strtr($inputStr, $t);
    }
    
public function downloadAttachment($file, $name) {
        ignore_user_abort(true);
        set_time_limit(0);

        $res = array('error' => 'null', 'err_code' => '0');
        //do something on download abort/finish
        //register_shutdown_function( 'function_name'  );
        if (!file_exists($file)) {
            $res['error'] = 'file not exist!';
            $res['err_code'] = 1;
            return $res;
        }

        $size = filesize($file);
        $name = rawurldecode($this->tstring_filename($name));

        if (preg_match('/Opera(\| )([0-9].[0-9]{1,2})/', $_SERVER['HTTP_USER_AGENT']))
            $UserBrowser = "Opera";
        elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $_SERVER['HTTP_USER_AGENT']))
            $UserBrowser = "IE";
        else
            $UserBrowser = '';

        /// important for download im most browser
        $mime_type = ($UserBrowser == 'IE' || $UserBrowser == 'Opera') ? 'application/octetstream' : 'application/octet-stream';
        @ob_end_clean(); /// decrease cpu usage extreme

        header('Content-Type: ' . $mime_type);
        header('Content-Disposition: attachment; filename="' . $name . '"');
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header('Accept-Ranges: bytes');
        header("Cache-control: private");
        header('Pragma: private');

        /////  multipart-download and resume-download
        if (isset($_SERVER['HTTP_RANGE'])) {
            list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);
            str_replace($range, "-", $range);
            $size2 = $size - 1;
            $new_length = $size - $range;

            header("HTTP/1.1 206 Partial Content");
            header("Content-Length: $new_length");
            header("Content-Range: bytes $range$size2/$size");
        } else {
            $size2 = $size - 1;
            header("Content-Length: " . $size);
        }

        $chunksize = 1 * (1024 * 1024);
        $bytes_send = 0;

        if ($file = fopen($file, 'r')) {
            if (isset($_SERVER['HTTP_RANGE']))
                fseek($file, $range);
            while (!feof($file) and (connection_status() == 0)) {
                $buffer = fread($file, $chunksize);
                print($buffer); //echo($buffer); // is also possible
                flush();
                $bytes_send += strlen($buffer);
                //sleep(1);//// decrease download speed
            }
            fclose($file);
        } else {
            $res['error'] = 'error can not open file!';
            $res['err_code'] = 2;
        }

        if (isset($new_length))
            $size = $new_length;

        return $res;
    }
}